﻿using Common.Models;
using Core.Entities.Mater;
using Core.Entities.SM;
using Core.Entities.Stock;
using Core.Interfaces;
using Infrastructure.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Infrastructure.Services.SM
{
    /// <summary>
    /// 库存台账服务
    /// </summary>
    public class StockService : BaseService<Stock, string>
    {
        private readonly IDapperRepository _dapperRepository;
        public FileLoggerService _log;

        // 注入其他实体的仓储
        private readonly IBaseRepository<StockIn, string> _stockInRepository;
        private readonly IBaseRepository<StockOut, string> _stockOutRepository;
        private readonly ApplicationDbContext _context; // 注入 DbContext
        public StockService(
            IBaseRepository<Stock, string> repository,
            IPagedRepository<Stock, string> pagedRepository,
            IDapperRepository dapperRepository, FileLoggerService fileLogger,
            IBaseRepository<StockIn, string> stockInRepository,  // 新增
            IBaseRepository<StockOut, string> stockOutRepository, ApplicationDbContext context)
            : base(repository, pagedRepository)
        {
            _dapperRepository = dapperRepository;
            _log = fileLogger;
            _stockInRepository = stockInRepository;
            _stockOutRepository = stockOutRepository;
             _context = context;
        }

        /// <summary>
        /// 根据物料编码查询库存
        /// </summary>
        /// <param name="materCode">物料编码</param>
        /// <returns>库存信息列表</returns>
        public async Task<IEnumerable<Stock>> GetByMaterCodeAsync(string materCode)
        {
            var filter = new QueryFilter
            {
                Conditions = new List<FilterCondition>
                {
                    new FilterCondition { Field = "MaterCode", Operator = "=", Value = materCode },
                    new FilterCondition { Field = "IsDeleted", Operator = "=", Value = false }
                }
            };

            var result = await _pagedRepository.GetPagedAsync(filter);
            return result.Data;
        }

        /// <summary>
        /// 根据批次号查询库存
        /// </summary>
        /// <param name="batchCode">批次号</param>
        /// <returns>库存信息列表</returns>
        public async Task<IEnumerable<Stock>> GetByBatchCodeAsync(string batchCode)
        {
            var filter = new QueryFilter
            {
                Conditions = new List<FilterCondition>
                {
                    new FilterCondition { Field = "BatchCode", Operator = "=", Value = batchCode },
                    new FilterCondition { Field = "IsDeleted", Operator = "=", Value = false }
                }
            };

            var result = await _pagedRepository.GetPagedAsync(filter);
            return result.Data;
        }

        /// <summary>
        /// 根据仓库ID查询库存
        /// </summary>
        /// <param name="warehouseId">仓库ID</param>
        /// <returns>库存信息列表</returns>
        public async Task<IEnumerable<Stock>> GetByWarehouseIdAsync(string warehouseId)
        {
            var filter = new QueryFilter
            {
                Conditions = new List<FilterCondition>
                {
                    new FilterCondition { Field = "WarehouseID", Operator = "=", Value = warehouseId },
                    new FilterCondition { Field = "IsDeleted", Operator = "=", Value = false }
                }
            };

            var result = await _pagedRepository.GetPagedAsync(filter);
            return result.Data;
        }

        /// <summary>
        /// 根据筒仓编码查询库存
        /// </summary>
        /// <param name="siloCode">筒仓编码</param>
        /// <returns>库存信息列表</returns>
        public async Task<IEnumerable<Stock>> GetBySiloCodeAsync(string siloCode)
        {
            var filter = new QueryFilter
            {
                Conditions = new List<FilterCondition>
                {
                    new FilterCondition { Field = "SiloCode", Operator = "=", Value = siloCode },
                    new FilterCondition { Field = "IsDeleted", Operator = "=", Value = false }
                }
            };

            var result = await _pagedRepository.GetPagedAsync(filter);
            return result.Data;
        }

        /// <summary>
        /// 高级分页查询库存
        /// </summary>
        /// <param name="filter">分页过滤器</param>
        /// <param name="stock">查询条件</param>
        /// <returns>分页结果</returns>
        public async Task<PagedResult<Stock>> AdvancedPagedQueryAsync(QueryFilter filter, Stock stock)
        {
            filter.Conditions = filter.Conditions ?? new List<FilterCondition>();

            // 添加物料编码查询条件
            if (!string.IsNullOrEmpty(stock.MaterCode))
            {
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "MaterCode",
                    Operator = "like",
                    Value = $"{stock.MaterCode}"
                });
            }

            // 添加物料名称查询条件
            if (!string.IsNullOrEmpty(stock.MaterName))
            {
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "MaterName",
                    Operator = "like",
                    Value = $"{stock.MaterName}"
                });
            }

            // 添加批次号查询条件
            if (!string.IsNullOrEmpty(stock.BatchCode))
            {
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "BatchCode",
                    Operator = "like",
                    Value = $"{stock.BatchCode}"
                });
            }

            // 添加仓库ID查询条件
            if (!string.IsNullOrEmpty(stock.WarehouseID))
            {
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "WarehouseID",
                    Operator = "=",
                    Value = stock.WarehouseID
                });
            }

            // 添加筒仓编码查询条件
            if (!string.IsNullOrEmpty(stock.SiloCode))
            {
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "SiloCode",
                    Operator = "=",
                    Value = stock.SiloCode
                });
            }

            // 添加库存类型查询条件
            if (!string.IsNullOrEmpty(stock.Type))
            {
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "Type",
                    Operator = "=",
                    Value = stock.Type
                });
            }

            // 添加库存状态查询条件
            if (!string.IsNullOrEmpty(stock.Status))
            {
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "Status",
                    Operator = "=",
                    Value = stock.Status
                });
            }

            // 添加最低数量查询条件
            if (stock.Quantity.HasValue)
            {
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "Quantity",
                    Operator = ">=",
                    Value = stock.Quantity.Value
                });
            }
            // 添加时间范围查询条件
            if (!string.IsNullOrEmpty(stock.StockTimeScope))
            {
                string[] dates = stock.StockTimeScope.Split('至');
                DateTime startDate = DateTime.Parse(dates[0].Trim());
                DateTime endDate = DateTime.Parse(dates[1].Trim());
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "CreateTime",
                    Operator = ">=",
                    Value = startDate
                });
                filter.Conditions.Add(new FilterCondition
                {
                    Field = "CreateTime",
                    Operator = "<=",
                    Value = endDate
                });
            }
            

            // 添加软删除过滤条件
            filter.Conditions.Add(new FilterCondition
            {
                Field = "IsDeleted",
                Operator = "=",
                Value = false
            });

            return await _pagedRepository.GetPagedAsync(filter);
        }

        #region 新增、修改、删除等业务
        /// <summary>
        /// 库存台账新增（台账新增时判断是出库还是入库记录，然后往出入库新增信息）
        /// </summary>
        /// <param name="stock"></param>
        /// <returns></returns>
        public async Task<ActionResult<Stock>> StockADD(Stock stock)
        {
            if (string.IsNullOrEmpty(stock.BatchCode))
            {
                throw new Exception("批次号不能为空");
            }
            if (string.IsNullOrEmpty(stock.MaterName) || string.IsNullOrEmpty(stock.MaterCode))
            {
                throw new Exception("物料名称或物料编码不能为空");
            }
            //先判断数据库中是否存在批次号，存在则不能新增
            string sql = @" select * from SM_Stock where BatchCode='"+ stock.BatchCode + "'";
            Stock StockEntity = await _dapperRepository.QueryFirstOrDefaultAsync<Stock>(sql);
            
            // 使用显式事务
            using var transaction = await _context.Database.BeginTransactionAsync();

            try
            {
                //物料信息核对
                sql = @" select * from BS_MaterInfo where MaterCode = @MaterCode";
                Mater_Info mater_Info = await _dapperRepository.QueryFirstOrDefaultAsync<Mater_Info>(sql, new { MaterCode= stock.MaterCode });
                if (mater_Info==null)
                {
                    throw new Exception("在物料信息中未能找到此物料：" + stock.MaterCode);
                }
                stock.MaterName = mater_Info.MaterName;
                stock.MaterType = mater_Info.materTepyName;
                //筒仓信息核对
                sql = @" select * from BS_Silo where 1=1 and Status!='10' and SiloCode = @Silo_Code and MaterCode = @MaterCode";
                SiloInfo BS_Silo = await _dapperRepository.QueryFirstOrDefaultAsync<SiloInfo>(sql, new { Silo_Code = stock.SiloCode , MaterCode = stock.MaterCode });
                if (BS_Silo == null)
                {
                    throw new Exception("在筒仓信息中未能找到此物料的筒仓：" + stock.MaterCode);
                }
                stock.SiloName = BS_Silo.SiloName;
                stock.Status = "已入库";

                //核对库存的数量是否超过筒仓的最高或者最低值
                string sqlST_Silo = @" select sum(Quantity) as Quantity from SM_Stock where Status='已入库' and SiloCode='" + BS_Silo.SiloCode + "'";
                Stock ST_Silo = await _dapperRepository.QueryFirstOrDefaultAsync<Stock>(sqlST_Silo);
                if (stock.Type=="入库")
                {
                    if (StockEntity != null)
                    {
                        throw new Exception("已存在此批次号(" + stock.BatchCode + ")，不能重复添加");
                    }
                    
                    //高于安全库存
                    if (ST_Silo.Quantity+ stock.Quantity > BS_Silo.MaxStockQty)
                    {
                        throw new Exception("以高于筒仓("+ BS_Silo.SiloName + ")安全库存");
                    }
                    
                    //-----------------新增库存台账----------------------
                    await _repository.AddAsync(stock);

                    //-----------------新增入库记录---------------------------
                    StockIn stockIn = new StockIn();
                    stockIn.Id = Guid.NewGuid().ToString();
                    stockIn.MaterCode = stock.MaterCode;
                    stockIn.MaterName = stock.MaterName;
                    stockIn.MaterType = stock.MaterType;
                    stockIn.WarehouseID = stock.WarehouseID;
                    stockIn.WarehouseName = stock.WarehouseName;
                    stockIn.LocationID = stock.LocationID;
                    stockIn.LocationName = stock.LocationName;
                    //stockIn.Unit = stock.Unit;
                    stockIn.In_Quantity = stock.Quantity;
                    stockIn.In_Type = "普通入库";//stock.Type;
                    stockIn.In_Time = stock.CreateTime;
                    stockIn.In_BatchCode = stock.BatchCode;
                    stockIn.Spec = stock.Spec;
                    stockIn.SiloCode = stock.SiloCode;
                    stockIn.SiloName = stock.SiloName;
                    await _stockInRepository.AddAsync(stockIn);
                }
                else if(stock.Type=="出库")
                {
                    //低于安全库存
                    if (ST_Silo.Quantity - stock.Quantity < BS_Silo.MinStockQty)
                    {
                        throw new Exception("以低于筒仓(" + BS_Silo.SiloName + ")安全库存");
                    }
                    //-----------------修改库存台账----------------------
                    StockEntity.OutTime = DateTime.Now;
                    StockEntity.Quantity -= stock.Quantity;
                    StockEntity.Status = "出库中";
                    if (StockEntity.Quantity<=0)
                    {
                        StockEntity.Status = "已出库";
                    }
                    await _repository.PartialUpdateAsync(StockEntity);

                    //------------------新增出库记录----------------------------
                    StockOut stockOut = new StockOut();
                    stockOut.Id = Guid.NewGuid().ToString();
                    stockOut.MaterCode = stock.MaterCode;
                    stockOut.MaterName = stock.MaterName;
                    stockOut.MaterType = stock.MaterType;
                    stockOut.WarehouseID = stock.WarehouseID;
                    stockOut.WarehouseName = stock.WarehouseName;
                    stockOut.LocationID = stock.LocationID;
                    stockOut.LocationName = stock.LocationName;
                    // stockOut.Unit = stock.Unit;
                    stockOut.OutQuantity = stock.Quantity;
                    stockOut.OutType = "普通出库";//stock.Type;
                    stockOut.OutTime = stock.CreateTime;
                    stockOut.OutBatchCode = stock.BatchCode;
                    stockOut.Spec = stock.Spec;
                    stockOut.SiloCode = stock.SiloCode;
                    stockOut.SiloName = stock.SiloName;
                    await _stockOutRepository.AddAsync(stockOut);
                }

                // 提交事务
                await transaction.CommitAsync();
                return stock;
            }
            catch (Exception ex)
            {
                // 回滚事务
                await transaction.RollbackAsync();
                throw new Exception($"库存台账新增失败: {ex.Message}");
            }
        }
        #endregion
    }
}